Package de.yaams.extensions.basemap.tiled.plugins.mappy

Source Code of de.yaams.extensions.basemap.tiled.plugins.mappy.MappyMapReader

/*
* Mappy Plugin for Tiled, (c) 2004-2006
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* Adam Turk <aturk@biggeruniverse.com> Bjorn Lindeijer <bjorn@lindeijer.nl>
*/

package de.yaams.extensions.basemap.tiled.plugins.mappy;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Vector;

import de.yaams.extensions.basemap.tiled.core.Map;
import de.yaams.extensions.basemap.tiled.core.MapLayer;
import de.yaams.extensions.basemap.tiled.core.ObjectGroup;
import de.yaams.extensions.basemap.tiled.core.Tile;
import de.yaams.extensions.basemap.tiled.core.TileLayer;
import de.yaams.extensions.basemap.tiled.core.TileSet;
import de.yaams.maker.helper.Log;

/**
* @version $Id$
*/
public class MappyMapReader {// implements MapReader {
  private LinkedList<Chunk> chunks;
  private Vector<BlkStr> blocks;
  private static final int BLKSTR_WIDTH = 32;
  private int twidth, theight;

  public static class BlkStr {
    public BlkStr() {}

    public long bg, fg0, fg1, fg2;
    public long user1, user2; // user long data
    public int user3, user4; // user short data
    public int user5, user6, user7; // user byte data
    public int bits; // collision and trigger bits
  }

  /**
   * Loads a map from a file.
   *
   * @param filename
   *            the filename of the map file
   */
  public Map readMap(String filename) throws Exception {
    return readMap(new FileInputStream(filename));
  }

  public Map readMap(InputStream in) throws Exception {
    Map ret = null;
    chunks = new LinkedList<Chunk>();
    blocks = new Vector<BlkStr>();
    byte[] hdr = new byte[4];

    in.read(hdr);
    long size = Util.readLongReverse(in);
    in.read(hdr);

    try {
      Chunk chunk = new Chunk(in);
      while (chunk.isGood()) {
        chunks.add(chunk);
        chunk = new Chunk(in);
      }
    } catch (IOException ioe) {
    }

    // now build a Tiled map...
    Chunk c = findChunk("MPHD");
    if (c != null) {
      ret = readMPHDChunk(c.getInputStream());
    } else {
      throw new IOException("No MPHD chunk found!");
    }

    c = findChunk("BODY");
    if (c != null) {
      readBODYChunk(ret, c.getInputStream());
    } else {
      throw new IOException("No BODY chunk found!");
    }

    return ret;
  }

  /**
   * Loads a tileset from a file.
   *
   * @param filename
   *            the filename of the tileset file
   */
  public TileSet readTileset(String filename) throws Exception {
    Log.ger.error("Tilesets aren't supported!");
    return null;
  }

  public TileSet readTileset(InputStream in) {
    Log.ger.error("Tilesets aren't supported!");
    return null;
  }

  /**
   * @see de.yaams.extensions.basemap.tiled.io.PluggableMapIO#getFilter()
   */
  public String getFilter() throws Exception {
    return "*.fmp";
  }

  public String getPluginPackage() {
    return "Mappy input plugin";
  }

  public String getDescription() {
    return "+---------------------------------------------+\n" + "|      An experimental reader for Mappy       |\n"
        + "|                 FMAP v0.36                  |\n" + "|            (c) Adam Turk 2004               |\n"
        + "|          aturk@biggeruniverse.com           |\n" + "|                                             |\n"
        + "| Currently unsupported:                      |\n" + "|  * Animated tiles                           |\n"
        + "|  * The ATHR block                           |\n" + "|  * Collision bits on BLKSTR structures      |\n"
        + "|  * bitdepths other than 16bit               |\n" + "|  * object layers                            |\n"
        + "+---------------------------------------------+";
  }

  public String getName() {
    return "Mappy Reader";
  }

  public boolean accept(File pathname) {
    try {
      String path = pathname.getCanonicalPath().toLowerCase();
      if (path.endsWith(".fmp")) {
        return true;
      }
    } catch (IOException e) {
    }
    return false;
  }

  private Chunk findChunk(String header) {
    Iterator<Chunk> itr = chunks.iterator();

    while (itr.hasNext()) {
      Chunk c = itr.next();
      if (c.equals(header)) {
        return c;
      }
    }
    return null;
  }

  private Map readMPHDChunk(InputStream in) throws IOException {
    Map ret = null;
    TileSet set = new TileSet();
    int major, minor;
    major = in.read();
    minor = in.read();
    in.skip(2); // skip lsb and reserved bytes - always msb
    ret = new Map(Util.readShort(in), Util.readShort(in));
    Properties retProps = ret.getProperties();
    ret.setOrientation(Map.MDO_ORTHO); // be sure to set the orientation!
    retProps.setProperty("(s)fmap reader", "Don't modify properties marked (s) unless you really know what you're doing.");
    retProps.setProperty("version", "" + major + "." + minor);
    in.skip(4); // reserved
    twidth = Util.readShort(in);
    theight = Util.readShort(in);
    ret.setTileWidth(twidth);
    ret.setTileHeight(theight);
    set.setName("Static tiles");
    ret.addTileset(set);
    int depth = Util.readShort(in);
    if (depth < 16) {
      throw new IOException("Tile bitdepths less than 16 are not supported!");
    }
    retProps.setProperty("(s)depth", String.valueOf(depth));
    in.skip(2);
    int numBlocks = Util.readShort(in);
    int numBlocksGfx = Util.readShort(in);
    Chunk c = findChunk("BKDT");
    if (c == null) {
      throw new IOException("No BKDT block found!");
    }
    MapLayer ml = new TileLayer(ret, ret.getWidth(), ret.getHeight());
    ml.setName("bg");
    ret.addLayer(ml);
    for (int i = 1; i < 7; i++) {
      // TODO: I believe this should be ObjectGroup
      ml = new ObjectGroup(ret, 0, 0);
      ml.setName("ObjectLayer " + i);
      ret.addLayer(ml);
    }
    ml = new TileLayer(ret, ret.getWidth(), ret.getHeight());
    ml.setName("fg 1");
    ret.addLayer(ml);
    ml = new TileLayer(ret, ret.getWidth(), ret.getHeight());
    ml.setName("fg 2");
    ret.addLayer(ml);
    ml = new TileLayer(ret, ret.getWidth(), ret.getHeight());
    ml.setName("fg 3");
    ret.addLayer(ml);

    readBKDTChunk(ret, c.getInputStream(), numBlocks);

    c = findChunk("BGFX");
    if (c != null) {
      readBGFXChunk(ret, c.getInputStream(), numBlocksGfx);
    } else {
      throw new IOException("No BGFX chunk found!");
    }

    Log.ger.debug(ret.toString());
    return ret;
  }

  private void readATHRChunk(Map m, InputStream in) {

  }

  private void readBKDTChunk(Map m, InputStream in, int num) throws IOException {
    Log.ger.debug("Reading " + num + " blocks...");
    for (int i = 0; i < num; i++) {
      blocks.add(readBLKSTR(in));
    }
  }

  /**
   * Read a BODY chunk from a Mappy map. BODY chunks contain data for the 4
   * main layers of the map.
   *
   * @param m
   * @param in
   * @throws IOException
   */
  private void readBODYChunk(Map m, InputStream in) throws IOException {
    TileSet set = m.getTilesets().get(0);
    TileLayer bg = (TileLayer) m.getLayer(0), fg0 = (TileLayer) m.getLayer(7), fg1 = (TileLayer) m.getLayer(8), fg2 = (TileLayer) m
        .getLayer(9);

    for (int i = 0; i < m.getHeight(); i++) {
      for (int j = 0; j < m.getWidth(); j++) {
        int block = (Util.readShort(in) & 0x00FF) / BLKSTR_WIDTH;
        // System.out.print("" + block);
        BlkStr blk = blocks.get(block);
        bg.setTileAt(j, i, set.getTile((int) blk.bg));
        fg0.setTileAt(j, i, set.getTile((int) blk.fg0));
        fg1.setTileAt(j, i, set.getTile((int) blk.fg1));
        fg2.setTileAt(j, i, set.getTile((int) blk.fg2));
      }
    }
  }

  /**
   * BGFX blocks are synonymous with {@link Tile}s
   *
   * @param m
   *            The Map to add Tiles to
   * @param in
   * @param num
   *            Number of Tiles to read
   * @throws IOException
   */
  private void readBGFXChunk(Map m, InputStream in, int num) throws IOException {
    TileSet set = m.getTilesets().get(0);
    set.addTile(new Tile());
    Util.readRawImage(in, twidth, theight); // skip the null-tile
    for (int i = 1; i < num; i++) {
      Tile t = new Tile();
      // t.setAppearance(image_id, 0);
      set.addTile(t);
    }
  }

  private BlkStr readBLKSTR(InputStream in) throws IOException {
    BlkStr ret = new BlkStr();
    long widthMod = twidth * theight * 512;
    ret.bg = Util.readLongReverse(in) / widthMod;
    ret.fg0 = Util.readLongReverse(in) / widthMod;
    ret.fg1 = Util.readLongReverse(in) / widthMod;
    ret.fg2 = Util.readLongReverse(in) / widthMod;

    ret.user1 = Util.readLongReverse(in);
    ret.user2 = Util.readLongReverse(in);
    ret.user3 = Util.readShort(in);
    ret.user4 = Util.readShort(in);
    ret.user5 = in.read();
    ret.user6 = in.read();
    ret.user7 = in.read();

    ret.bits = in.read();

    return ret;
  }
}
TOP

Related Classes of de.yaams.extensions.basemap.tiled.plugins.mappy.MappyMapReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.